﻿using System;
using System.Collections.Generic;
using Bling.DSL;
using Bling.Util;
using Bling.Core;
using linq = Microsoft.Linq.Expressions;

namespace Bling.Core {


}

namespace Bling.NewProperties {


  public abstract class PropertyExpr<T> : Expr<T> {

  }
  public class PropertyExpr<S, T> : PropertyExpr<T> {
    public readonly Expr<S> Source;
    public readonly Property<S, T> Property;
    public PropertyExpr(Expr<S> Source, Property<S, T> Property) { this.Source = Source; this.Property = Property;  }
    protected override int GetHashCode0() {
      return Source.GetHashCode() + Property.GetHashCode();
    }
    protected override bool Equals0(Expr<T> e) {
      return e is PropertyExpr<S, T> &&
        ((PropertyExpr<S, T>)e).Source.Equals(Source) &&
        ((PropertyExpr<S, T>)e).Property.Equals(Property);
    }
    protected override string ToString1() {
      return Source.ToString() + "." + Property.Name;
    }
    protected override Eval<EVAL>.Info<T> Eval<EVAL>(Eval<EVAL> txt) {
      return Property.Eval(txt, Source);
    }
    public override bool Solve(IAssign P, Expr<T> RHS) {
      if (Property.Solve(P, Source, RHS)) return true;
      else return base.Solve(P, RHS);
    }
  }
  public  abstract class Property<S, T> {
    public PropertyExpr<S, T> this[Expr<S> Source] { get { return new PropertyExpr<S, T>(Source, this); } }
    public abstract string Name { get; }
    protected internal abstract Eval<EVAL>.Info<T> Eval<EVAL>(Eval<EVAL> txt, Expr<S> Source) where EVAL : Eval<EVAL>;
    public override string ToString() { return Name; }
    protected internal virtual bool Solve(IAssign P, Expr<S> Source, Expr<T> RHS) { return false; }

  }
}